package com.an.pay.service.Impl;

import com.an.pay.client.AliPayClient;
import com.an.pay.client.WxPayClient;
import com.an.pay.entity.AliParams;
import com.an.pay.entity.WxPayParams;
import com.an.pay.enums.OrderStatus;
import com.an.pay.enums.PayType;
import com.an.pay.mapper.OrderInfoMapper;
import com.an.pay.service.OrderInfoService;
import com.an.pay.service.ProductService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.an.pay.entity.OrderInfo;
import com.an.pay.entity.Product;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service
@Slf4j
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo>implements OrderInfoService {

    @Autowired
    private WxPayClient client;
    @Autowired
    private AliPayClient aliPayClient;
    @Autowired
    private ProductService productService;


    @Override
    @Transactional
    public Map<String, String> pay(Long productId,String payType) throws Exception {
        // 1. 根据 productId 查询商品
        Product product = productService.getById(productId);
        if(product == null){
            throw new RuntimeException("没 【"+ productId+"商品");
        }
        // 2. 创建订单
        OrderInfo orderInfo = this.createOrder(product,payType);
        log.info("orderInfo===={}",orderInfo);
        this.save(orderInfo);
        Map<String, String> map = null;
        if(payType.equals(PayType.WXPAY.getType())){
             map = wxPay(orderInfo);
        }
        else {
            String formStr = aliPay(orderInfo);
             map = new HashMap<>(1);
             map.put("formStr",formStr);
        }
        return map;
    }

    private String aliPay(OrderInfo orderInfo) {
        AliParams aliParams = AliParams.builder()
                .outTradeNo(orderInfo.getOrderNo())
                .total(orderInfo.getTotalFee())
                .subject(orderInfo.getTitle())
                .build();
        return aliPayClient.pay(aliParams);
    }

    private Map<String, String> wxPay(OrderInfo orderInfo) throws Exception {
        //2. 根据查询的商品信息封装微信支付需要的参数 WxPayParams
        WxPayParams wxPayParams = WxPayParams.builder()
                .description(orderInfo.getTitle())//标题
                .outTradeNo(orderInfo.getOrderNo()) // 订单号
                .total(orderInfo.getTotalFee()) // 支付金额
                .build();
        //3. 调用 微信支付client
        Map<String, String> map = client.nativePay(wxPayParams);
        return map;
    }

    private OrderInfo createOrder(Product product,String payType) {
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setTitle(product.getTitle());
        orderInfo.setTotalFee(product.getPrice());
        orderInfo.setOrderStatus(OrderStatus.NOTPAY.getType());
        orderInfo.setOrderNo(UUID.randomUUID().toString().substring(10));
        orderInfo.setProductId(Long.valueOf(product.getId()));
        orderInfo.setPaymentType(payType);
        return orderInfo;
    }

    @Override
    public String getOrderStatus(String orderNo) {
        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no", orderNo);
        OrderInfo orderInfo = baseMapper.selectOne(queryWrapper);
        if(orderInfo == null){
            return null;
        }
        return orderInfo.getOrderStatus();
    }

    @Override
    public List<OrderInfo> getNoPayOrderByDuration(int minutes, String paymentType) {
        Instant instant = Instant.now().minus(Duration.ofMinutes(minutes));
        log.info("当前的时间为=={}",instant);
        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_status", OrderStatus.NOTPAY.getType());
        queryWrapper.le("create_time", instant);
        queryWrapper.eq("payment_type", paymentType);

        List<OrderInfo> orderInfoList = baseMapper.selectList(queryWrapper);

        return orderInfoList;
    }


}
